package com.rtsapp.server.utils;


import io.netty.buffer.ByteBuf;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Arrays;

public class RC4Utils {

    static final int N = 256;

    private short[] s = new short[N];

    public RC4Utils(byte[] key) {

        short[] k = new short[N];
        for (int i = 0; i < N; i++) {
            s[i] = (short) i;
            k[i] = key[i % key.length];
        }

        int j = 0;
        short temp = 0;
        for (int i = 0; i < N; i++) {
            j = (j + s[i] + k[i]) % 256;
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
    }

    public void crpyt(byte[] buffer) {
        short[] s = new short[N];
        System.arraycopy(this.s, 0, s, 0, this.s.length);

        int i = 0, j = 0, t = 0;
        int k = 0;
        short tmp;
        for (k = 0; k < buffer.length; k++) {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            tmp = s[i];
            s[i] = s[j];//交换s[x]和s[y]
            s[j] = tmp;
            t = (s[i] + s[j]) % 256;
            buffer[k] ^= s[t];
        }

    }


    public void crpyt( ByteBuf buffer, int begin, int end ) {

        byte v;

        short[] s = new short[N];
        System.arraycopy(this.s, 0, s, 0, this.s.length);

        int i = 0, j = 0, t = 0;
        int k = 0;
        short tmp;
        for (k = begin; k < end; k++) {
            i = (i + 1) % 256;
            j = (j + s[i]) % 256;
            tmp = s[i];
            s[i] = s[j];//交换s[x]和s[y]
            s[j] = tmp;
            t = (s[i] + s[j]) % 256;

            v = buffer.getByte(k);
            v ^= s[t];
            buffer.setByte(k, v);
        }
    }


    public void crpytFile(File srcFile, File destFile) {
        try {
            FileInputStream fis = new FileInputStream(srcFile);
            int size = fis.available();
            byte[] fileBytes = new byte[size];
            fis.read(fileBytes, 0, size);
            fis.close();

            crpyt(fileBytes);

            if (!destFile.getParentFile().exists()) {
                destFile.getParentFile().mkdirs();
            }

            FileOutputStream fos = new FileOutputStream(destFile);
            fos.write(fileBytes, 0, size);
            fos.flush();
            fos.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void crpytDir(File srcDir, File destDir) {
        File[] files = srcDir.listFiles();
        for (File f : files) {
            if (f.isFile()) {
                crpytFile(f, new File(destDir, f.getName()));
            } else {
                crpytDir(f, new File(destDir, f.getName()));
            }
        }
    }

    public static void main(String[] args) {
        RC4Utils rc = new RC4Utils("hellodytqwe123".getBytes());

        byte[] b1 = {1, 1, 1, 1, 1, 1, 1, 1};
        byte[] b2 = {1, 1, 1, 1};
        byte[] b3 = {1, 1, 1, 1};

        rc.crpyt(b1);
        rc.crpyt(b2);
        rc.crpyt(b3);
        System.out.println(Arrays.toString(b1));
        System.out.println(Arrays.toString(b2));
        System.out.println(Arrays.toString(b3));

        rc.crpyt(b1);
        rc.crpyt(b2);
        rc.crpyt(b3);
        System.out.println(Arrays.toString(b1));
        System.out.println(Arrays.toString(b2));
        System.out.println(Arrays.toString(b3));
    }
}
